/*
 * @Author: Morphlng
 * @Date: 2022-04-05 18:24:54
 * @LastEditTime: 2022-04-06 18:50:17
 * @LastEditors: Morphlng
 * @Description: A simple timer class in C++, using RAII feature.
 * @FilePath: \Cish\useful_trick\Timer.h
 */
#pragma once
#include <chrono>
#include <iostream>

/*
    A C++11 Timer class for debugging.
    Usage:
        1. The Timer class uses RAII feature, it will start
        once you create an instance, and stop when it gets
        destroyed. Time elapsed will print to console.
        2. You can also manually stop the timer, and
        call restart to use it again.
*/
class Timer
{
public:
    Timer() : start_time(std::chrono::high_resolution_clock::now()), running(true) {}

    ~Timer()
    {
        if (running)
            stop();
    }

    void restart()
    {
        running = true;
        start_time = std::chrono::high_resolution_clock::now();
    }

    double stop()
    {
        auto endTimeStamp = std::chrono::high_resolution_clock::now();
        running = false;

        auto start = std::chrono::time_point_cast<std::chrono::microseconds>(start_time).time_since_epoch().count();
        auto end = std::chrono::time_point_cast<std::chrono::microseconds>(endTimeStamp).time_since_epoch().count();

        auto duration = end - start;
        double ms = duration * 1e-3;

        std::cout << "Time cost: " << duration << "us (" << ms << "ms)\n";

        // if your application don't have a console, you can use this return value
        return ms;
    }

private:
    std::chrono::time_point<std::chrono::high_resolution_clock> start_time;
    bool running;
};